#ifndef _FEATURE_H_
#define _FEATURE_H_

#include <vector>
#include <string>


#include "gflags/gflags.h"
#include "glog/logging.h"
#include "opencv2/core.hpp"
#include "opencv2/opencv.hpp"
#include "opencv2/xfeatures2d.hpp"

// abstract class of feature
class Feature {
public:
  Feature();
  virtual ~Feature() = 0;  //pure virtual function 

  // load image from image file name
  bool LoadImg(const std::string& s);
  // load image from Feature object
  bool LoadImg(const Feature& feat);

  // get the key points
  const std::vector<cv::KeyPoint>& keypoint() { return keypoints_; }
  const std::vector<cv::KeyPoint>& keypoint() const {return keypoints_; }

  // get the descriptors
  const cv::Mat& desc() { return desc_; }
  const cv::Mat& desc() const {return desc_; }

  // get the image mat
  const cv::Mat& img() const {
    return img_;
  }

  const std::string& img_file() const {
    return img_file_;
  }

  // extract feature point and descriptor
  bool ExtractFeature(bool with_desc);
  
  // get the matcher
  const cv::BFMatcher* const matcher() { return matcher_; }
  const cv::BFMatcher* const matcher() const { return matcher_; }

  // get the feature extractor
  const cv::Ptr<cv::Feature2D> ptrFeature2D() const {
    return keypt_dect_;
  }

protected:
  // image
  std::string img_file_;
  cv::Mat img_;
  // feature key points 
  std::vector<cv::KeyPoint> keypoints_;
  // feature descriptors matrix
  cv::Mat desc_;
  // matcher
  cv::BFMatcher* matcher_;
  // feature detector
  cv::Ptr<cv::Feature2D> keypt_dect_;
};


// SIFT feature class 
class FeatureSift : public Feature {

public:
  FeatureSift();
  ~FeatureSift();

private:
  // matcher
  static cv::BFMatcher* sift_matcher_;
  // feature detector
  static cv::Ptr<cv::Feature2D> sift_keypt_dect_;
};

// BRISK feature class
class FeatureBrisk : public Feature {
public:
  FeatureBrisk();
  ~FeatureBrisk();

protected:
  // matcher
  static cv::BFMatcher* brisk_matcher_;
  // feature detector
  static cv::Ptr<cv::Feature2D> brisk_keypt_dect_;
};


#endif // _FEATURE_H_